import 'dart:convert';
import 'dart:developer';
import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sports_new/controller/service/config_service.dart';
import 'package:sports_new/entity/other/error_info_entity.dart';
import 'package:sports_new/utils/constant.dart';
import 'package:sports_new/utils/user.dart';
import 'package:sports_new/utils/utils.dart';
import '../entity/other/app_update_entity.dart';
import '../entity/other/auth_entity.dart';
import '../entity/record/recent_channel_entity.dart';

typedef Json = Map<String, dynamic>;

class SpUtils {
  static late SharedPreferences sp;

  static const localReadHistoryKey = "localReadHistory";
  // static const _homeDataKey = "homeData";
  static const _loginAuthKey = "loginAuth";
  static const _updateInfoKey = "appUpdateInfoKey";
  static const _agreePrivacyKey = "agreePrivacy";
  static const _baseUrlKey = "baseUrl";
  static const _matchAllFilterDataKey = "matchAllFilterData";
  static const _requestNotification = "requestNotification";
  //一级 热门比赛
  static const _matchOneLevelKey = "matchOneLevelKey";
  static const _basketOneLevelKey = "basketOneLevelKey";
  static const _appUuid = "appUuid";
  static const _appContactKey = "appContact";
  static const _appTipsKey = "appTips";
  static const _expertContactKey = "expertContact";
  static const _localSettingsKey = "localSettings";
  static const _appLaunchKey = "appLaunch";
  static const _gift4NewuserKey = "gift4newuser";
  static const _showFocusTeamKey = "showFocusTeam";
  //设置
  static const _soccerConfigKey = "soccerConfig";
  static const _basketConfigKey = "basketConfig";
  static const _pushConfigKey = "pushConfig";
  static const _configTimeKey = "configTime";
  static const _notifySetted = "notifySetted";
  static const _lbtDialogIds = "lbtDialogIds";
  static const _autoDownload = "autoDownload";
  static const _suggestPush = "suggestPush";
  static const _apkPath = "apkPath";
  //广告
  static const _matchZqAds = "matchZqAds";
  static const _matchLqAds = "matchLqAds";
  static const _floatAds = "floatAds";
  static const _personalAds = "personalAds";
  //版本更新提醒
  static const _versionIgnore = "versionCheck";
  static const _versionIgnoreSet = "versionCheckSet";
  //app评价
  static const _appLaunchNum = "appLaunchNum";
  static const _appReview = "appReview";
  //比赛频道引导
  static const _matchGuide = "matchGuide";
  //搜索记录
  static const _searchHistory = "searchHistory";
  //报错日志
  static const _errorInfo = "errorInfo";
  static const _showErrorToast = "showErrorToast";
  static const _proxyEnabled = "proxyEnabled";
  static const _proxyUrl = "proxyUrl";
  //比赛详情点击标记
  static const _planClick = Constant.guandian;
  static const _aiClick = Constant.model;
  static const _infoClick = Constant.baoliao;
  //最近访问联赛
  static const _zqRecent = "zqRecent";
  static const _lqRecent = "lqRecent";
  //分享好友点击
  static const _shareClick = "shareCheck";
  //一键关注弹窗
  static const _suggestExpert = 'suggestExpert';
  //优惠券包广告
  static const _couponSale = "couponSale";
  // 方案-彩经-专家榜-分页tab 上次点击的index
  static const _expertTabIndex = "expertTabIndex";
  static const _expertLqTabIndex = "expertLqTabIndex";
  // 方案-彩经-分页内容
  static const _expertZqContentIndex = "expertZqContentIndex";
  static const _expertLqContentIndex = "expertLqContentIndex";
  // 比赛-详情-分页
  static const _matchDetailZqTabIndex = "matchDetailZqTabIndex";
  static const _matchDetailLqTabIndex = "matchDetailLqTabIndex";

  static initSp() async {
    sp = await SharedPreferences.getInstance();
    if (!sp.getStringList(_matchLqAds).hasValue)
      sp.setStringList(_matchLqAds, List.generate(5, (index) => ""));
    if (!sp.getStringList(_matchZqAds).hasValue)
      sp.setStringList(_matchZqAds, List.generate(5, (index) => ""));
    showErrorToast = false;
  }

  static bool? get agreePrivacy {
    return sp.getBool(_agreePrivacyKey);
  }

  static set agreePrivacy(bool? value) {
    sp.setBool(_agreePrivacyKey, value ?? false);
  }

  static bool? get showFocusTeam {
    return sp.getBool(_showFocusTeamKey + (User.auth?.userId ?? ''));
  }

  static set showFocusTeam(bool? value) {
    sp.setBool(_showFocusTeamKey + (User.auth?.userId ?? ''), value ?? false);
  }

  static bool setJson(String key, Map<String, dynamic>? json) {
    try {
      if (json == null) {
        sp.remove(key);
      } else {
        final str = jsonEncode(json);
        sp.setString(key, str);
      }
      return true;
    } catch (err) {
      log("set json data err $err");
      return false;
    }
  }

  static Map<String, dynamic>? getJson(String key) {
    try {
      final str = sp.getString(key)!;
      return jsonDecode(str);
    } catch (err) {
      log("get json err $err");
    }
  }

  // static Map<String, dynamic>? get homeData => getJson(_homeDataKey);
  // static set homeData(Map<String, dynamic>? json) =>
  //     setJson(_homeDataKey, json);

  static Map<String, dynamic>? get matchAllFilterData =>
      getJson(_matchAllFilterDataKey);
  static set matchAllFilterData(Map<String, dynamic>? json) =>
      setJson(_matchAllFilterDataKey, json);

  static Map<String, dynamic>? get matchOneLevelKey =>
      getJson(_matchOneLevelKey);
  static set matchOneLevelKey(Map<String, dynamic>? json) =>
      setJson(_matchOneLevelKey, json);

  static Map<String, dynamic>? get basketOneLevelKey =>
      getJson(_basketOneLevelKey);
  static set basketOneLevelKey(Map<String, dynamic>? json) =>
      setJson(_basketOneLevelKey, json);

  static AuthEntity? _loginAuth;
  static AuthEntity? get loginAuth {
    if (_loginAuth != null) {
      return _loginAuth;
    }
    final str = sp.getString(_loginAuthKey);
    try {
      final json = jsonDecode(str ?? "");
      final auth = AuthEntity.fromJson(json);
      _loginAuth = auth;
      return auth;
    } catch (err) {
      log("sp utils get login err ${err}");
      return null;
    }
  }

  static set loginAuth(AuthEntity? en) {
    try {
      _loginAuth = en;
      final json = en?.toJson();
      final str = jsonEncode(json);
      sp.setString(_loginAuthKey, str);
    } catch (err) {
      if (en == null) {
        sp.remove(_loginAuthKey);
      }
      log("set login auth err ${err}");
    }
  }

  static AppUpdateEntity? get appUpdateInfo {
    final infostr = sp.getString(_updateInfoKey);
    if (infostr == null) {
      return null;
    }
    try {
      final json = jsonDecode(infostr);
      return AppUpdateEntity.fromJson(json);
    } catch (err) {
      log("get app update info err $err");
      return null;
    }
  }

  static set appUpdateInfo(AppUpdateEntity? info) {
    if (info == null) {
      sp.remove(_updateInfoKey);
      return;
    }
    try {
      final str = jsonEncode(info.toJson());
      sp.setString(_updateInfoKey, str);
    } catch (err) {
      log("set app update info err $err");
    }
  }

  static String get baseUrl =>
      sp.getString(_baseUrlKey) ??
      (kDebugMode ? Constant.testBaseUrl : Constant.prodBaseUrl);
  static set baseUrl(String v) =>
      v.isEmpty ? sp.remove(_baseUrlKey) : sp.setString(_baseUrlKey, v);

  static String? get appUuid => sp.getString(_appUuid);

  static set appUuid(String? uuid) {
    sp.setString(_appUuid, uuid ?? "");
  }

  static String? get appUdid => sp.getString(_appUuid);

  static set appUdid(String? udid) {
    sp.setString(_appUuid, udid ?? "");
  }

  static Json? get appContact => getJson(_appContactKey);
  static set appContact(Json? value) => setJson(_appContactKey, value);

  static List? get appTips => getJson(_appTipsKey)?['list'];
  static set appTips(List? l) => setJson(_appTipsKey, {"list": l});

  static Json? get expertContact => getJson(_expertContactKey) ?? {};
  static set expertContact(Json? json) => setJson(_expertContactKey, json);

  static Json get localSettings => getJson(_localSettingsKey) ?? {};
  static set localSettings(Json json) => setJson(_localSettingsKey, json);

  static List? get appLaunch => getJson(_appLaunchKey)?['list'];
  static set appLaunch(List? list) => setJson(_appLaunchKey, {"list": list});

  static Json get gift4newuser => getJson(_gift4NewuserKey) ?? {};
  static set gift4newuser(Json json) => setJson(_gift4NewuserKey, json);

  static ZqConfig? get soccerConfig {
    final infostr = sp.getString(_soccerConfigKey);
    if (infostr == null) {
      return null;
    }
    try {
      Map<String, dynamic> json = jsonDecode(infostr);
      Map<int, String> intJson = Map<int, String>();
      for (var key in json.keys) {
        intJson[int.parse(key)] = json[key] ?? '';
      }
      return ZqConfig.fromJson(intJson);
    } catch (err) {
      return null;
    }
  }

  static set soccerConfig(ZqConfig? info) {
    if (info == null) {
      sp.remove(_soccerConfigKey);
      return;
    }
    try {
      final str = jsonEncode(info.toStringJson());
      sp.setString(_soccerConfigKey, str);
    } catch (err) {
      log('sp utils err');
    }
  }

  static LqConfig? get basketConfig {
    final data = sp.getString(_basketConfigKey);
    if (data == null) {
      return null;
    }
    try {
      final json = jsonDecode(data);
      Map<int, String> intJson = Map<int, String>();
      for (var key in json.keys) {
        intJson[int.parse(key)] = json[key] ?? '';
      }
      return LqConfig.fromJson(intJson);
    } catch (err) {
      return null;
    }
  }

  static set basketConfig(LqConfig? data) {
    if (data == null) {
      sp.remove(_basketConfigKey);
      return;
    }
    try {
      final str = jsonEncode(data.toStringJson());
      sp.setString(_basketConfigKey, str);
    } catch (err) {}
  }

  static PushConfig? get pushConfig {
    final data = sp.getString(_pushConfigKey);
    if (data == null) {
      return null;
    }
    try {
      final json = jsonDecode(data);
      Map<int, String> intJson = Map<int, String>();
      for (var key in json.keys) {
        intJson[int.parse(key)] = json[key] ?? '';
      }
      return PushConfig.fromJson(intJson);
    } catch (err) {
      return null;
    }
  }

  static set pushConfig(PushConfig? data) {
    if (data == null) {
      sp.remove(_pushConfigKey);
      return;
    }
    try {
      final str = jsonEncode(data.toStringJson());

      sp.setString(_pushConfigKey, str);
    } catch (err) {}
  }

  static int? get configTime {
    return sp.getInt(_configTimeKey);
  }

  static set configTime(int? value) {
    sp.setInt(_configTimeKey, value ?? 0);
  }

  static bool get notifySetted => sp.getBool(_notifySetted) ?? false;
  static set notifySetted(bool v) => sp.setBool(_notifySetted, v);

  static List<String> get lbtDialogIds => sp.getStringList(_lbtDialogIds) ?? [];
  static set lbtDialogIds(List<String>? n) {
    if (n == null) {
      sp.remove(_lbtDialogIds);
    } else {
      sp.setStringList(_lbtDialogIds, n);
    }
  }

  static bool? get requestNotification {
    return sp.getBool(_requestNotification);
  }

  static set requestNotification(bool? value) {
    sp.setBool(_requestNotification, value ?? true);
  }

  static bool? get autoDownload {
    return sp.getBool(_autoDownload);
  }

  static set autoDownload(bool? value) {
    sp.setBool(_autoDownload, value ?? true);
  }

  static bool get personalAds {
    return sp.getBool(_personalAds) ?? true;
  }

  static set personalAds(bool? value) {
    sp.setBool(_personalAds, value ?? false);
  }

  static bool? get suggestPush {
    return sp.getBool(_suggestPush);
  }

  static set suggestPush(bool? value) {
    sp.setBool(_suggestPush, value ?? true);
  }

  static String? get apkPath {
    return sp.getString(_apkPath);
  }

  static set apkPath(String? value) {
    sp.setString(_apkPath, value ?? "");
  }

  static int? get appLaunchNum {
    return sp.getInt(_appLaunchNum);
  }

  static set appLaunchNum(int? value) {
    sp.setInt(_appLaunchNum, value ?? 0);
  }

  static bool? get appReview {
    return sp.getBool(_appReview);
  }

  static set appReview(bool? value) {
    sp.setBool(_appReview, value ?? true);
  }

  static bool? get matchGuide {
    return sp.getBool(_matchGuide);
  }

  static set matchGuide(bool? value) {
    sp.setBool(_matchGuide, value ?? true);
  }

  static List<String>? get matchLqAds => sp.getStringList(_matchLqAds);

  static void setMatchLqAds(int index, String value) {
    List<String>? list = sp.getStringList(_matchLqAds);
    list?[index] = value;
    sp.setStringList(_matchLqAds, list ?? []);
  }

  static List<String>? get matchZqAds {
    return sp.getStringList(_matchZqAds);
  }

  static void setMatchZqAds(int index, String value) {
    List<String>? list = sp.getStringList(_matchZqAds);
    list?[index] = value;
    sp.setStringList(_matchZqAds, list ?? []);
  }

  static Json? get floatAds {
    return sp.getString(_floatAds).noValue
        ? null
        : jsonDecode(sp.getString(_floatAds) ?? "");
  }

  static void setFloatAds(Json map) {
    String? ads = sp.getString(_floatAds);
    if (ads.hasValue) {
      Json adsMap = jsonDecode(ads!);
      if (adsMap.containsKey(map.keys.first)) {
        adsMap.update(map.keys.first, (value) => map.values.first);
      } else {
        adsMap[map.keys.first] = map.values.first;
      }
      sp.setString(_floatAds, jsonEncode(adsMap));
    } else {
      sp.setString(_floatAds, jsonEncode(map));
    }
  }

  static String? get versionIgnore {
    return sp.getString(_versionIgnore);
  }

  static set versionIgnore(String? value) {
    sp.setString(_versionIgnore, value ?? "");
  }

  static int get suggestExpert {
    return sp.getInt(_suggestExpert) ?? 0;
  }

  static set suggestExpert(int? value) {
    sp.setInt(_suggestExpert, value ?? 0);
  }

  static int get couponSale {
    return sp.getInt(_couponSale) ?? 0;
  }

  static set couponSale(int? value) {
    sp.setInt(_couponSale, value ?? 0);
  }

  static bool get shareClick {
    return sp.getBool(_shareClick) ?? false;
  }

  static set shareClick(bool? value) {
    sp.setBool(_shareClick, value ?? false);
  }

  static String? get versionIgnoreSet {
    return sp.getString(_versionIgnoreSet);
  }

  static set versionIgnoreSet(String? value) {
    sp.setString(_versionIgnoreSet, value ?? "");
  }

  static List<String>? get searchHistory {
    return sp.getStringList(_searchHistory);
  }

  static void setSearchHistory(String value, {int? index}) {
    List<String>? list = sp.getStringList(_searchHistory);
    if (index != null) {
      list?[index] = value;
    } else {
      list ??= [];
      list.add(value);
    }
    sp.setStringList(_searchHistory, list ?? []);
  }

  static void deleteSearchHistory() {
    sp.setStringList(_searchHistory, []);
  }

  static List<String>? get errorInfo {
    return sp.getStringList(_errorInfo);
  }

  static void setErrorInfo(ErrorInfoEntity entity) {
    List<String>? list = sp.getStringList(_errorInfo);
    if (list != null) {
      list.add(jsonEncode(entity));
      if (list.length > 100) list.removeAt(0);
    } else {
      list ??= [];
      list.add(jsonEncode(entity));
    }
    sp.setStringList(_errorInfo, list);
  }

  static void deleteErrorInfo() {
    sp.setStringList(_errorInfo, []);
  }

  static bool get showErrorToast {
    return sp.getBool(_showErrorToast) ?? true;
  }

  static set showErrorToast(bool value) {
    sp.setBool(_showErrorToast, value);
  }

  static bool get proxyEnabled {
    return sp.getBool(_proxyEnabled) ?? false;
  }

  static set proxyEnabled(bool value) {
    sp.setBool(_proxyEnabled, value);
  }

  static String get proxyUrl {
    return sp.getString(_proxyUrl) ?? '';
  }

  static set proxyUrl(String value) {
    sp.setString(_proxyUrl, value);
  }

  static List<String>? getMatchClick(String type) {
    return sp.getStringList(type);
  }

  static void setMatchClick(String type, String value) {
    List<String>? list = sp.getStringList(type);
    list ??= [];
    if (list.length > 100) {
      list.removeAt(0);
    }
    if (!list.contains(value)) {
      list.add(value);
      sp.setStringList(type, list);
    }
  }

  static List<RecentChannelEntity> getMatchRecent(int sportsId) {
    return sp
            .getStringList(sportsId == 1 ? _zqRecent : _lqRecent)
            ?.reversed
            .map((e) => RecentChannelEntity.fromJson(jsonDecode(e)))
            .toList() ??
        [];
  }

  static void setMatchRecent(RecentChannelEntity entity, int sportsId) {
    String value = jsonEncode(entity);
    List<String>? list =
        sp.getStringList(sportsId == 1 ? _zqRecent : _lqRecent);
    list ??= [];
    if (list.length >= 9) {
      list.removeAt(0);
    }
    if (!list.contains(value)) {
      list.add(value);
      sp.setStringList(sportsId == 1 ? _zqRecent : _lqRecent, list);
    }
  }

  static void deleteMatchRecent(int sportsId) {
    sp.setStringList(sportsId == 1 ? _zqRecent : _lqRecent, []);
  }

  static int? get expertTabIndex {
    return sp.getInt(_expertTabIndex);
  }

  static set expertTabIndex(int? value) {
    sp.setInt(_expertTabIndex, value ?? 0);
  }

  static int? get expertLqTabIndex {
    return sp.getInt(_expertLqTabIndex);
  }

  static set expertLqTabIndex(int? value) {
    sp.setInt(_expertLqTabIndex, value ?? 0);
  }

  static int? get expertZqContentIndex {
    return sp.getInt(_expertZqContentIndex);
  }

  static set expertZqContentIndex(int? value) {
    sp.setInt(_expertZqContentIndex, value ?? 0);
  }

  static int? get expertLqContentIndex {
    return sp.getInt(_expertLqContentIndex);
  }

  static set expertLqContentIndex(int? value) {
    sp.setInt(_expertLqContentIndex, value ?? 0);
  }

  static int? get matchDetailZqTabIndex {
    return sp.getInt(_matchDetailZqTabIndex);
  }

  static set matchDetailZqTabIndex(int? value) {
    sp.setInt(_matchDetailZqTabIndex, value ?? 0);
  }

  static int? get matchDetailLqTabIndex {
    return sp.getInt(_matchDetailLqTabIndex);
  }

  static set matchDetailLqTabIndex(int? value) {
    sp.setInt(_matchDetailLqTabIndex, value ?? 0);
  }
}
